﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;
using UIDesigner.Designers.Forms;
using System.Drawing.Design;
using UIDesigner.Designers;
using UIDesigner.DesignContainers.Bases;
using UIDesigner.Editors;

namespace UIDesigner.SurfaceProperties
{
    public class SurfaceCategoryType : IPropertyCollectionProvider
    {
        private Type m_objEnumType;
        private SurfacePropertyCategory m_eCategory;
        private int m_nOption;
        private AFDesignerHost m_objHost;
        private PropertyDescriptorCollection m_rgPropertyCollection;
        private IBaseObjectControl m_objControl;
        private SurfacePropertiesBase m_objSurrogateProperties;

        public SurfaceCategoryType(Type objEnumType, SurfacePropertyCategory eCategory, int nOption, AFDesignerHost objHost, IBaseObjectControl objControl)
        {
            m_objEnumType = objEnumType;
            m_eCategory = eCategory;
            m_objHost = objHost;
            m_objControl = objControl;
            m_nOption = nOption;
        }

        public SurfaceCategoryType(Type objEnumType, SurfacePropertyCategory eCategory, int nOption, AFDesignerHost objHost, IBaseObjectControl objControl, SurfacePropertiesBase objSurrogateProperties)
        {
            m_objEnumType = objEnumType;
            m_eCategory = eCategory;
            m_objHost = objHost;
            m_objControl = objControl;
            m_nOption = nOption;
            m_objSurrogateProperties = objSurrogateProperties;
        }

        public override string ToString()
        {
            return "[" + Enum.GetName(m_objEnumType, m_nOption) + "]";
        }

        public PropertyDescriptorCollection PropertyCollection
        {
            get 
            {
                if (m_rgPropertyCollection == null)
                {
                    PropertyDescriptor[] rgProperties;
                    Attribute[] rgAttr;

                    switch (m_eCategory)
                    {
                        case SurfacePropertyCategory.ObjectCreation:

                            rgProperties = new PropertyDescriptor[2];

                            if (m_objSurrogateProperties != null)
                            {
                                rgProperties[0] = new SurfaceCreateDescriptor(m_objHost, m_objControl, SurfaceCreatePropertyKind.CreateOption, null, m_objSurrogateProperties);
                            }
                            else
                            {
                                rgAttr = new Attribute[1];
                                rgAttr[0] = new EditorAttribute(typeof(DynamicEnumEditor), typeof(UITypeEditor));

                                rgProperties[0] = new SurfaceCreateDescriptor(m_objHost, m_objControl, SurfaceCreatePropertyKind.CreateOption, rgAttr);
                            }

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new EditorAttribute(typeof(SurfaceStateEditor), typeof(UITypeEditor));
                            rgProperties[1] = new SurfaceCreateDescriptor(m_objHost, m_objControl, SurfaceCreatePropertyKind.CreateState, rgAttr, m_objSurrogateProperties);

                            m_rgPropertyCollection = new PropertyDescriptorCollection(rgProperties);

                            break;

                        case SurfacePropertyCategory.ObjectSave:

                            rgProperties = new PropertyDescriptor[4];

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new EditorAttribute(typeof(DynamicEnumEditor), typeof(UITypeEditor));
                            rgProperties[0] = new SurfaceSaveDescriptor(m_objHost, m_objControl, SurfaceSavePropertyKind.SaveOption, rgAttr, m_objSurrogateProperties);

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new EditorAttribute(typeof(DynamicEnumEditor), typeof(UITypeEditor));
                            rgProperties[1] = new SurfaceSaveDescriptor(m_objHost, m_objControl, SurfaceSavePropertyKind.SaveMessage, rgAttr, m_objSurrogateProperties);

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new EditorAttribute(typeof(SurfaceStateEditor), typeof(UITypeEditor));
                            rgProperties[2] = new SurfaceSaveDescriptor(m_objHost, m_objControl, SurfaceSavePropertyKind.SaveState, rgAttr, m_objSurrogateProperties);

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new EditorAttribute(typeof(PostActionEditor), typeof(UITypeEditor));
                            rgProperties[3] = new SurfaceDeleteDescriptor(m_objHost, m_objControl, SurfaceDeletePropertyKind.PostActions, rgAttr, m_objSurrogateProperties);

                            m_rgPropertyCollection = new PropertyDescriptorCollection(rgProperties);

                            break;

                        case SurfacePropertyCategory.ObjectDeletion:

                            rgProperties = new PropertyDescriptor[4];

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new EditorAttribute(typeof(DynamicEnumEditor), typeof(UITypeEditor));
                            rgProperties[0] = new SurfaceDeleteDescriptor(m_objHost, m_objControl, SurfaceDeletePropertyKind.DeleteOption, rgAttr, m_objSurrogateProperties);

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new EditorAttribute(typeof(ConfirmOptionsEditor), typeof(UITypeEditor));
                            rgProperties[1] = new SurfaceDeleteDescriptor(m_objHost, m_objControl, SurfaceDeletePropertyKind.ConfirmOption, rgAttr, m_objSurrogateProperties);

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new EditorAttribute(typeof(SurfaceStateEditor), typeof(UITypeEditor));
                            rgProperties[2] = new SurfaceDeleteDescriptor(m_objHost, m_objControl, SurfaceDeletePropertyKind.DeleteState, rgAttr, m_objSurrogateProperties);

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new EditorAttribute(typeof(PostActionEditor), typeof(UITypeEditor));
                            rgProperties[3] = new SurfaceDeleteDescriptor(m_objHost, m_objControl, SurfaceDeletePropertyKind.PostActions, rgAttr, m_objSurrogateProperties);

                            m_rgPropertyCollection = new PropertyDescriptorCollection(rgProperties);

                            break;

                        case SurfacePropertyCategory.ObjectBinding:

                            rgProperties = new PropertyDescriptor[5];

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new TypeConverterAttribute(typeof(EnumConverter));
                            rgProperties[0] = new SurfaceBindDescriptor(m_objHost, m_objControl, SurfaceBindPropertyKind.BindOption, rgAttr, m_objSurrogateProperties);

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new TypeConverterAttribute(typeof(EnumConverter));
                            rgProperties[1] = new SurfaceBindDescriptor(m_objHost, m_objControl, SurfaceBindPropertyKind.PreBindOptions, rgAttr, m_objSurrogateProperties);

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new TypeConverterAttribute(typeof(EnumConverter));
                            rgProperties[2] = new SurfaceBindDescriptor(m_objHost, m_objControl, SurfaceBindPropertyKind.PostBindExistingOptions, rgAttr, m_objSurrogateProperties);

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new TypeConverterAttribute(typeof(EnumConverter));
                            rgProperties[3] = new SurfaceBindDescriptor(m_objHost, m_objControl, SurfaceBindPropertyKind.PostBindNewOptions, rgAttr, m_objSurrogateProperties);

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new EditorAttribute(typeof(SurfaceStateEditor), typeof(UITypeEditor));
                            rgProperties[4] = new SurfaceBindDescriptor(m_objHost, m_objControl, SurfaceBindPropertyKind.BindState, rgAttr, m_objSurrogateProperties);

                            m_rgPropertyCollection = new PropertyDescriptorCollection(rgProperties);

                            break;

                        case SurfacePropertyCategory.UIReset:

                            rgProperties = new PropertyDescriptor[2];

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new EditorAttribute(typeof(DynamicEnumEditor), typeof(UITypeEditor));
                            rgProperties[0] = new SurfaceResetDescriptor(m_objHost, m_objControl, SurfaceResetPropertyKind.ResetOption, rgAttr, m_objSurrogateProperties);

                            rgAttr = new Attribute[1];
                            rgAttr[0] = new EditorAttribute(typeof(ConfirmOptionsEditor), typeof(UITypeEditor));
                            rgProperties[1] = new SurfaceResetDescriptor(m_objHost, m_objControl, SurfaceResetPropertyKind.ResetConfirmOption, rgAttr, m_objSurrogateProperties);

                            m_rgPropertyCollection = new PropertyDescriptorCollection(rgProperties);

                            break;

                        default:

                            Debugger.Break();
                            break;
                    }

                }

                return m_rgPropertyCollection;
            }
        }
    }

    public class SurfaceCategoryDescriptor : PropertyDescriptor
    {
        private AFDesignerHost m_objHost;
        private SurfacePropertyCategory m_eCategory;
        private IBaseObjectControl m_objControl;
        private SurfacePropertiesBase m_objSurrogateProperties;

        public SurfaceCategoryDescriptor(AFDesignerHost objHost, IBaseObjectControl objControl, SurfacePropertyCategory eCategory, Attribute[] rgAttributes) : base(Enum.GetName(typeof(SurfacePropertyCategory), eCategory), rgAttributes)
		{
            m_objHost = objHost;
            m_eCategory = eCategory;
            m_objControl = objControl;
		}

        public SurfaceCategoryDescriptor(AFDesignerHost objHost, IBaseObjectControl objControl, SurfacePropertyCategory eCategory, Attribute[] rgAttributes, SurfacePropertiesBase objSurrogateProperties) : base(Enum.GetName(typeof(SurfacePropertyCategory), eCategory), rgAttributes)
		{
            m_objHost = objHost;
            m_eCategory = eCategory;
            m_objControl = objControl;
            m_objSurrogateProperties = objSurrogateProperties;
		}

        private SurfacePropertiesBase SurfaceProperties
        {
            get
            {
                if (m_objSurrogateProperties == null)
                {
                    return m_objHost.SurfacePropertiesSet[m_objControl];
                }
                else
                {
                    return m_objSurrogateProperties;
                }
            }
        }

		public override bool CanResetValue(object component)
		{
			return false;
		}

		public override Type ComponentType
		{
			get 
            {
                return m_objHost.RootComponent.GetType(); 
            }
		}

		public override object GetValue(object component)
		{
            SurfaceCategoryType objType = null;

            switch (m_eCategory)
            {
                case SurfacePropertyCategory.ObjectBinding:

                    objType = new SurfaceCategoryType(typeof(BindStateOptions), m_eCategory, (int)this.SurfaceProperties.BindProperties.BindStateOptions, m_objHost, m_objControl, m_objSurrogateProperties);
                    break;

                case SurfacePropertyCategory.ObjectCreation:

                    objType = new SurfaceCategoryType(typeof(CreateOptions), m_eCategory, (int)this.SurfaceProperties.CreateProperties.CreateOptions, m_objHost, m_objControl, m_objSurrogateProperties);
                    break;

                case SurfacePropertyCategory.ObjectSave:

                    objType = new SurfaceCategoryType(typeof(SaveOptions), m_eCategory, (int)this.SurfaceProperties.SaveProperties.SaveOptions, m_objHost, m_objControl, m_objSurrogateProperties);
                    break;

                case SurfacePropertyCategory.ObjectDeletion:

                    objType = new SurfaceCategoryType(typeof(DeleteOptions), m_eCategory, (int)this.SurfaceProperties.DeleteProperties.DeleteOptions, m_objHost, m_objControl, m_objSurrogateProperties);
                    break;

                case SurfacePropertyCategory.UIReset:

                    objType = new SurfaceCategoryType(typeof(ResetOptions), m_eCategory, (int)this.SurfaceProperties.ResetProperties.ResetOptions, m_objHost, m_objControl, m_objSurrogateProperties);
                    break;

            }

            return objType;
		}

		public override bool IsReadOnly
		{
			get 
            {
                return true; 
            }
		}

		public override Type PropertyType
		{
			get 
            {
                return typeof(SurfaceCategoryType); 
            }
		}

		public override void ResetValue(object component)
		{
			
		}

		public override void SetValue(object component, object value)
		{
		}

		public override bool ShouldSerializeValue(object component)
		{
			return false;
		}

		public override string Category
		{
			get
			{
				return "Surface Properties";
			}
		}

		public override string Description
		{
			get
			{
				return "Shows the hidden field names\r\nAlthough these properties exists at the selected object's type you cannot see them as editable";
			}
		}
    }
}
